package com.code.upload.utils;

import com.code.upload.vo.QiNiuPutRetVo;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Random;

@Component
@Slf4j
public class QiNiuUtil {

    @Value("${qiniu.accessKey}")
    private String accessKey;

    @Value("${qiniu.secretKey}")
    private String secretKey;

    @Value("${qiniu.bucket}")
    private String bucket;

    @Value("${qiniu.domainOfBucket}")
    private String domainOfBucket;

    private Configuration config = new Configuration(new Zone.Builder().upHttp("http://upload.qiniup.com").upHttps("https://upload.qiniup.com").
            upBackupHttp("http://up.qiniup.com").upBackupHttps("https://up.qiniup.com").
            iovipHttp("http://iovip.qbox.me").iovipHttps("https://iovip.qbox.me").
            rsHttp("http://rs.qiniu.com").rsHttps("https://rs.qbox.me")
            .rsfHttp("http://rsf.qiniu.com").rsfHttps("https://rsf.qbox.me")
            .apiHttp("http://api.qiniu.com").apiHttps("https://api.qiniu.com").build());

    /*
    上传管理器
     */
    private final UploadManager um = new UploadManager(config);

    /**
     * 获取认证
     * @param accessKey
     * @param secretKey
     * @return
     */
    public Auth getAuth(String accessKey, String secretKey) {
        return Auth.create(accessKey, secretKey);
    }

    /**
     * 单独获取 token 提供给 APP 端使用
     */
    public String getToken() {
        String token = null;
        try {
            token = getAuth(accessKey, secretKey).uploadToken(bucket);
        } catch (Exception e) {
            log.error("-----获取七牛token异常：{}", e);
        }
        return token;
    }

    /**
     * 文件上传
     * @param inputStream
     * @param key  上传存储名称
     */
    public String upload(InputStream inputStream, String key) {
        String result = "error";
        try {
            Response response = um.put(inputStream, key, getToken(), null, null);
            int retry = 0;
            // 若发送失败,则重复上传,保证文件上传成功
            while (response.needRetry() && retry < 3) {
                response = um.put(inputStream, key, getToken(), null, null);
                retry++;
            }
            // 上传成功返回存储路径
            result = key;
            // 解析上传成功的结果
            QiNiuPutRetVo putRet = new Gson().fromJson(response.bodyString(), QiNiuPutRetVo.class);
            log.info("upload success: " + putRet);
        } catch (QiniuException e) {
            Response r = e.response;
            if (null != r) {
                log.error(r.toString());
            }
            log.error("upload failed！");
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 文件下载
     * @param fileName 下载文件名称
     *                 访问域名
     */
    public String download(String fileName) {
        // 下载成功返回访问链接
        String result = null;
        try {
            String encodedFileName = URLEncoder.encode(fileName, "utf-8");
            String finalUrl = String.format("%s/%s", domainOfBucket, encodedFileName);
            result = finalUrl;
            log.info("get the file url: " + finalUrl);
        } catch (UnsupportedEncodingException e) {
            log.error("get the file url failed", e);
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 文件删除
     * @param key 上传时的文件存储路径
     * @return
     */
    public void delete(String key) {
        // 空间操作器
        BucketManager bucketManager = new BucketManager(getAuth(accessKey, secretKey), config);
        try {
            bucketManager.delete(bucket, key);
            log.info("delete success");
        } catch (QiniuException e) {
            // 如果遇到异常，说明删除失败
            log.error("delete failed, code:{}, response:{}.", e.code(), e.response.toString());
            e.printStackTrace();
        }
    }

    /**
     * 设置目录层级
     */
    public String createKey() {
        Random random = new Random();

        String firstFolder = "0" + random.nextInt(10); // 一级目录
        int temp = random.nextInt(100); // 二级目录

        String seceondFolder;
        if (temp < 10) {
            seceondFolder = firstFolder + "_0" + temp;
        } else {
            seceondFolder = firstFolder + "_" + temp;
        }

        String thirdFolder; // 三级目录
        int temp1 = random.nextInt(1000);
        if (temp1 < 10) {
            thirdFolder = seceondFolder + "_00" + temp1;
        } else if (temp1 > 9 && temp1 < 100) {
            thirdFolder = seceondFolder + "_0" + temp1;
        } else {
            thirdFolder = seceondFolder + "_" + temp1;
        }

        String url = File.separator + "qbm_" + firstFolder + File.separator + seceondFolder + File.separator + thirdFolder
                + File.separator;
        return url;
    }

}

